const { Op } = require("sequelize");
const User = require('../db/sequelize/model/User');
const { isValidEmail } = require('../utils/regexValidate');
const reminder = require('../lib/reminder');

async function registerUser(username, password, email) {
  const newUser = await User.create({
    username,
    password,
    email
  });
  return {
    id: newUser.dataValues.id
  };
}

async function loginUser(loginName) {
  const loginField = isValidEmail(loginName) ? 'email' : 'username';
  const user = await User.findOne({
    where: {
      [loginField]: loginName
    }
  });
  if (user == null) return null;
  const { id, username, email, password: hashPwd } = user.dataValues;
  return { id, username, email, hashPwd };
}

async function findDuplicateUser(fields) {
  const allowedConditions = ['username', 'email'];
  const conditions = [];
  for (let condition of allowedConditions) {
    if (fields[condition]) {
      conditions.push({ [condition]: fields[condition] });
    }
  }
  const user = await User.findOne({
    where: {
      [Op.or]: conditions
    }
  });
  return {
    exist: !!user
  };
}

async function findUserById(userId) {
  const user = await User.findByPk(userId, {
    attributes: { exclude: ['password', 'updatedAt'] }
  });
  return user.dataValues;
}

async function changeUserPwd(id, password) {
  const res = await User.update(
    { password },
    {
      where: { id }
    }
  );
  return !!res[0];
}

async function deleteUser(userId) {
  const user = await User.findByPk(userId);
  const tasks = await user.getTasks();
  await Promise.all(
    tasks.filter(task => {
      const value = task.dataValues;
      if (!value.isCompleted
        && value.remindTime
        && value.remindTime.getTime() > Date.now()
      ) {
        return reminder.removeTaskReminder(userId, value.id);
      }
    })
  );

  const res = await user.destroy();
  return !!res;
}

module.exports = {
  registerUser,
  loginUser,
  findDuplicateUser,
  findUserById,
  changeUserPwd,
  deleteUser
};
